package newgen;

import java.util.ArrayList;
import java.util.List;

/**
 * 关于jstat显示统计信息说明http://blog.csdn.net/maosijunzi/article/details/46049117
 *
 *1 新生代较小 导致fullgc  释放调大 新生代20->30
 * 调整新生代大小 20->30 微gc减少 同时新生代空间能够支撑tmpObjects中的对象大小到下次微gc，下次微gc发现置为null，会回收掉，所以不会触发fullgc
 * Created by zhj on 15-11-13.
 * -Xms135M -Xmx135M -Xmn30M -XX:+UseSerialGC
 * 分别含义是 s0百分比  Eden百分比 老年代百分比
 *  S0     S1     E      O      M     CCS    YGC     YGCT    FGC    FGCT     GCT
 *  0.00   0.00  12.00   0.00  15.13  17.34      0    0.000     0    0.000    0.000
 0.00   0.00   1.97  90.16  63.18  65.97      6    0.081     1    0.031    0.111
 0.00   0.00   1.97  90.16  63.18  65.97      6    0.081     1    0.031    0.111
 0.00   0.00   1.97  90.16  63.18  65.97      6    0.081     1    0.031    0.111
 0.00   0.00   1.97  90.16  63.18  65.97      6    0.081     1    0.031    0.111
 0.00   0.00   1.97  90.16  63.18  65.97      6    0.081     1    0.031    0.111

 2 新生代过大 导致老年代变小 fullgc频繁 同时微gc时间增加
 * -Xms135M -Xmx135M -Xmn105M -XX:+UseSerialGC
 * 对比30M情况，微gc少了，但full gc多了一次，原因在于第二次到达微gc触发条件,jvm基于悲观原则，判断老年代剩余小于新生代晋升，于是full gc，同时单次微gc时间也长了不少
 *
 * 0.00   0.00   8.00   0.00  15.13  17.34      0    0.000     0    0.000    0.000
 0.00 100.00 100.00  46.80  15.13  17.34      1    0.000     0    0.000    0.000
 0.00   0.00  89.73 100.00  63.19  65.97      1    0.097     2    0.101    0.198
 0.00   0.00  89.73 100.00  63.19  65.97      1    0.097     2    0.101    0.198
 0.00   0.00  89.73 100.00  63.19  65.97      1    0.097     2    0.101    0.198
 0.00   0.00  89.73 100.00  63.19  65.97      1    0.097     2    0.101    0.198
 0.00   0.00  89.73 100.00  63.19  65.97      1    0.097     2    0.101    0.198
 0.00   0.00  89.73 100.00  63.19  65.97      1    0.097     2    0.101    0.198


 10752.0 10752.0  0.0    0.0   86016.0   6881.5   31744.0      0.0     4480.0 677.9  384.0   66.6       0    0.000   0      0.000    0.000
 10752.0 10752.0  0.0    0.0   86016.0  82775.3   31744.0      0.0     4480.0 677.9  384.0   66.6       1    0.000   0      0.000    0.000
 10752.0 10752.0  0.0    0.0   86016.0  75030.3   31744.0    31744.0   4864.0 3074.2 512.0  337.8       1    0.103   2      0.099    0.202
 10752.0 10752.0  0.0    0.0   86016.0  77179.6   31744.0    31744.0   4864.0 3074.2 512.0  337.8       1    0.103   2      0.099    0.202
 10752.0 10752.0  0.0    0.0   86016.0  77179.6   31744.0    31744.0   4864.0 3074.2 512.0  337.8       1    0.103   2      0.099    0.202
 10752.0 10752.0  0.0    0.0   86016.0  77179.6   31744.0    31744.0   4864.0 3074.2 512.0  337.8       1    0.103   2      0.099    0.202
 10752.0 10752.0  0.0    0.0   86016.0  77179.6   31744.0    31744.0   4864.0 3074.2 512.0  337.8       1    0.103   2      0.099    0.202
 10752.0 10752.0  0.0    0.0   86016.0  77179.6   31744.0    31744.0   4864.0 3074.2 512.0  337.8       1    0.103   2      0.099    0.202

3 总上 新生代一般设置占heap的33%左右


 4 避免survivor过小或过大
 -Xms135M -Xmx135M -Xmn20M -XX:+UseSerialGC -XX：SurvivorRatio=10
 该配置避免了2次full gc，在没有SurvivorRatio该配置场景下，默认Eden为16M，tmpObjects创建时会填满Eden，触发微gc，此时16M都被引用，不能释放，
        所以只能都放入幸存区，但幸存区只有2M，因此14M直接转入老年代，老年代加上之前的101M左右空间，超过115M空间，所以触发full gc
    加入-XX：SurvivorRatio=10 后，Eden为16.7M，tmpObjects不足以触发微gc,full gc也就避免了

 经验：SurvivorRatio变大，Eden变大，微gc次数变少，幸存区变小，如果微gc后存活对象超过幸存区，则会直接晋升
        反之调小，则微gc频繁，幸存区变大后则可以存储更多微gc后仍存活的对象,避免直接进入老年代
 5 增大存活次数  可以使对象在微gc阶段被回收机会增加，但同时幸存区被占用

 */
public class GCDemo {
    public static void main(String[] args) throws InterruptedException {
        System.out.println("ready to start");
        Thread.sleep(10000*3);

        List<GCDataObject> oldGenObjects=new ArrayList<>();
        for (int i=0;i<51200;i++){//大约需要100M空间
            //每次创建2k对象
            oldGenObjects.add(new GCDataObject(2));
        }

        //触发full gc
        System.gc();

        System.out.println(oldGenObjects.size());
        oldGenObjects=null;

        Thread.sleep(5000);

        List<GCDataObject> tmpObjects=new ArrayList<>();
        for (int i=0;i<3200;i++){//大约需要16M空间
            //每次创建2k对象
            tmpObjects.add(new GCDataObject(5));
        }

        System.out.println(tmpObjects.size());
        tmpObjects=null;
    }
}
